<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>Create a heatmap layer</title>
    <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
    <script src="lib/jquery-3.6.0.min.js"></script>
    <link href="lib/mapbox-gl2.6.1.css" rel="stylesheet">
    <script src="lib/mapbox-gl2.6.1.js"></script>
    <script src='lib/mapbox-gl-language.js'></script>
    <script src="lib/dat.gui.min.js"></script>
    <script src="lib/turf.min.js"></script>
    <script src="lib/kriging.js"></script>
    <style>
        body {
            margin: 0;
            padding: 0;
        }

        #map {
            position: absolute;
            top: 0;
            bottom: 0;
            width: 100%;
        }
    </style>
</head>

<body>
    <div id="map"></div>

    <script>
        /** 点图层geojson等值线，全省的话做到乡级。村级计算量太大 */
        mapboxgl.accessToken = 'pk.eyJ1IjoiaG91eGlleXUiLCJhIjoiY2pldjE5amU3NndzeDM5bzd5bm9ncDgycyJ9.j1F-Lgid3L5k2Abm8_xTeQ';
        const map = new mapboxgl.Map({
            container: 'map',
            style: 'mapbox://styles/mapbox/dark-v10',
            center: [117.125829, 36.656704],
            zoom: 8
        });

        map.on('load', async () => {
            // Add a geojson point source.
            // Heatmap layers also work with a vector tile source.
            let ipapi = '6ql20nip.ipyingshe.net';
            // let ip1 = '192.168.0.53:8080';
            let level = 'xiang'
            let field = 'f176'
            let tileurl = `http://${ipapi}/geoserver/gwc/service/tms/1.0.0/rp7%3Agv_${level}_pt@EPSG%3A900913@pbf/{z}/{x}/{y}.pbf`;

            //查询点图层数据
            let url2 = encodeURI(`http://${ipapi}/geoserver/rp7/ows?service=WFS&version=1.0.0&request=GetFeature&outputFormat=application/json&typeName=rp7:gv_${level}_pt&propertyName=geom,${field}&format_options=id_policy:reference_no=false&cql_filter=code like '%'`)
            // let url2 = `http://${ip1}/features?fields=${field}&level=${level}&geotype=point`

            let geores = await $.getJSON(url2);
            //获取最大最小值
            let minmax = await $.getJSON(`http://${ipapi}/getminmax?field=f176&level=${level}`);
            let min = minmax.min;
            let max = minmax.max;

            //查询外轮廓
            // let urlsheng = `http://${ip1}/geoserver/rp7/ows?service=WFS&version=1.0.0&request=GetFeature&outputFormat=application/json&typeName=rp7:g_shi&cql_filter=code like '3701'&propertyName=geom&format_options=id_policy:reference_no=false`;
            // let geosheng = await $.getJSON(urlsheng);
            // console.log(geosheng)
            /** 参数配置组件 */
            var options = {
                'title': '热力图',
                weight: 1,
                weightmin: min,
                weightmax: max,
                intensity: 1,
                radius: 40,
            };
            initOptions(map, options,field);

            /** 生成等值面 */
            /** 克里金插值 */
            // let gridcollection = createkirginggrid(geores,field,geosheng);

            /** 反距离插值 */
            let gridcollection = createturfgird(geores, field)
            // console.log(gridcollection)

            //生成等值面图
            createBands(map,gridcollection,field);

            //生成插值图
            // createGridLayer(map,gridcollection,field);
            // createGridLayer(map,geores,field);
        });

        function createGridLayer(map,gridcollection,field){
            map.addSource("gridpoint", {
                type: "geojson",
                data: gridcollection
            });
            map.addLayer({
                id: "gridpoint",
                // type: "circle",
                type: "symbol",
                source: "gridpoint",
                layout: {'text-field':`{${field}}`},
                // paint: {
                //     "circle-color":'red',
                //     'circle-radius':1
                // }
            });
        }

        function createturfgird(geores, field) {
            var interpolate_options = {
                gridType: "points",
                property: field,
                units: "degrees",
                weight: 10
            };
            var gridcollection = turf.interpolate(geores, 0.03, interpolate_options);
            // 适当降低插值结果的精度便于显示
            gridcollection.features.map((i) => (i.properties[field] = Math.round(i.properties[field])));
            return gridcollection;
        }

        function createkirginggrid(geores, field, outline) {
            let arr_x = geores.features.map(ft => ft.geometry.coordinates[0]);
            let arr_y = geores.features.map(ft => ft.geometry.coordinates[1]);
            let arr_z = geores.features.map(ft => ft.properties[field]);
            var model = "exponential";
            var sigma2 = 0, alpha = 100;
            var fitModel = kriging.train(arr_z, arr_x, arr_y, model, sigma2, alpha);
            console.log(arr_x)
            console.log(fitModel)
            let bboxout = turf.bbox(outline);
            let bboxpolygon = turf.bboxPolygon(bboxout);
            let width = 0.01;
            var krgrid = kriging.grid(bboxpolygon.geometry.coordinates, fitModel, width);
            let fc = gridFeatureCollection(krgrid);
            var gridcollection = turf.featureCollection(fc);
            return gridcollection;

            function gridFeatureCollection(grid) {
                var range = grid.zlim[1] - grid.zlim[0];
                var i, j, x, y, z;
                var n = grid.length;//列数
                var m = grid[0].length;//行数
                var pointArray = [];
                for (i = 0; i < n; i++)
                    for (j = 0; j < m; j++) {
                        x = (i) * grid.width + grid.xlim[0];
                        y = (j) * grid.width + grid.ylim[0];
                        // z = (grid[i][j] - grid.zlim[0]) / range;
                        // if (z < 0.0) z = 0.0;
                        // if (z > 1.0) z = 1.0;
                        pointArray.push(turf.point([x, y], { value: grid[i][j] }));
                    }
                return pointArray;
            }
        }

        function createBands(map, gridcollection,field) {
            var isobands_options = {
                zProperty: field,
                commonProperties: {
                    "fill-opacity": 0.8
                },
                breaksProperties: [
                    //  { fill: "#006837" },
                    // { fill: "#1a9850" },
                    // { fill: "#66bd63" },
                    // { fill: "#a6d96a" },
                    // { fill: "#d9ef8b" },
                    // { fill: "#ffffbf" },
                    { fill: "#fee08b" },
                    { fill: "#fdae61" },
                    { fill: "#f46d43" },
                    { fill: "#d73027" },
                    { fill: "#a50026" }
                ]
            };
            var isobands = turf.isobands(
                gridcollection,
                // [0,100,500, 1000, 2000, 5000, 10000,20000,30000],
                [1000,10000,20000, 40000, 500000],
                isobands_options
            );

            map.addSource("isobans", {
                type: "geojson",
                data: isobands
            });
            map.addLayer({
                id: "isobans",
                type: "fill",
                source: "isobans",
                layout: {},
                paint: {
                    "fill-color": ["get", "fill"],
                    "fill-opacity": [
                        "case",
                        ["boolean", ["feature-state", "hover"], false],
                        0.8,
                        0.5
                    ],
                    "fill-outline-color": [
                        "case",
                        ["boolean", ["feature-state", "hover"], false],
                        "#000",
                        "#fff"
                    ]
                }
            });

        }

        function initOptions(map, options, field) {
                var gui = new dat.GUI();

                gui.add(options, 'title');
                var ctlweight = gui.add(options, 'weight').min(0).max(1).name('人数权重');
                ctlweight.onChange(function (value) {
                    map.setPaintProperty('cun-heat', 'heatmap-weight', [
                        'interpolate', ['linear'], ['get', field], options.weightmin, 0, options.weightmax, value
                    ])
                });
                var ctlintensity = gui.add(options, 'intensity').min(0).max(10).name('总体强度');
                var ctlradius = gui.add(options, 'radius').min(0).max(100).name('热力半径');
                ctlintensity.onChange(function (value) {
                    map.setPaintProperty('cun-heat', 'heatmap-intensity', value)
                });
                ctlradius.onChange(function (value) {
                    map.setPaintProperty('cun-heat', 'heatmap-radius', value)
                });
            }
    </script>

</body>

</html>